﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.GraphicsInterface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CadDotNetTools
{
    public enum FontCharSet
    {
        Ansi = 0,   //英文
        Default = 1,  //与当前操作系统语言有关
        GB2312 = 134,  //简体中文
        Big5 = 136,  //繁体中文
        OEM = 255,  //与操作系统有关
    }
    public enum FontPitch
    {
        Default = 0, //默认字宽
        Fixed = 1,  //固定字宽
        Variable = 2,  //可变字宽
    }
    public enum FontFamily
    {
        Dontcare = 0, //默认字体
        Roman = 16, //可变的笔画宽度，有衬线，如 MS Serif 字体
        Swiss = 32,  //可变的笔画宽度，无衬线,如MS Sans Serif 字体
        Modern = 48,    //固定笔画宽度，衬线可有可无，如Courier New 字体
        Script = 64,    //手写体 ， 如 Cursive 字体
        Decorative = 80,    //小说字体，如旧式英语
    }
    public static class TextStyleTools
    {
        /// <summary>
        /// 创建新的文字样式
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="styleName">文字样式</param>
        /// <param name="fontFileName">字体文件名</param>
        /// <param name="bigFontFileName">大字体文件名</param>
        /// <returns></returns>
        public static ObjectId AddTextStyle(this Database db, string styleName, string fontFileName, string bigFontFileName)
        {
            //打开文字样式表
            var st = db.TextStyleTableId.GetObject(OpenMode.ForRead) as TextStyleTable;
            //如果不存在名为styleName的文字样式,则新建一个文字样式
            if (!st.Has(styleName))
            {
                //定义一个新的文字样式表记录
                var str = new TextStyleTableRecord();
                //设置文字样式名
                str.Name = styleName;
                //设置字体文件名
                str.FileName = fontFileName;
                //设置大字体文件名
                str.BigFontFileName = bigFontFileName;
                //切换文字样式的状态为写以添加新的文字样式
                st.UpgradeOpen();
                //将文字样式表记录的信息添加到文字样式表中
                st.Add(str);
                //把文字样式表记录添加到事物处理中
                db.TransactionManager.AddNewlyCreatedDBObject(str, true);
                //为了安全，将文字样式表的状态切换为读
                st.DowngradeOpen();
            }

            return st[styleName];  //返回新添加的文字样式记录的ObjectId
        }

        /// <summary>
        /// 创建新的文字样式
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="styleName">文字样式</param>
        /// <param name="fontFileName">字体文件名</param>
        /// <returns></returns>
        public static ObjectId AddTextStyle(this Database db, string styleName, string fontFileName)
        {
            return db.AddTextStyle(styleName, fontFileName, "");  //返回新添加的文字样式记录的ObjectId
        }

        /// <summary>
        /// 创建新的文字样式
        /// </summary>
        /// <param name="db">图形数据库</param>
        /// <param name="styleName">文字样式</param>
        /// <param name="fontFileName">字体文件名</param>
        /// <param name="bold">是否加粗</param>
        /// <param name="italic">是否倾斜</param>
        /// <param name="charset">字体的字符集</param>
        /// <param name="pitchAndFamily">字体的字宽和语系定义</param>
        /// <returns></returns>
        public static ObjectId AddTextStyle(this Database db, string styleName, string fontFileName, bool bold, bool italic, int charset, int pitchAndFamily)
        {
            //打开文字样式表
            var st = db.TextStyleTableId.GetObject(OpenMode.ForRead) as TextStyleTable;
            //如果不存在名为styleName的文字样式,则新建一个文字样式
            if (!st.Has(styleName))
            {
                //定义一个新的文字样式表记录
                var str = new TextStyleTableRecord();
                //设置文字样式名
                str.Name = styleName;
                //设置文字样式的字体
                str.Font = new FontDescriptor(fontFileName, bold, italic, charset, pitchAndFamily);

                //切换文字样式的状态为写以添加新的文字样式
                st.UpgradeOpen();
                //将文字样式表记录的信息添加到文字样式表中
                st.Add(str);
                //把文字样式表记录添加到事物处理中
                db.TransactionManager.AddNewlyCreatedDBObject(str, true);
                //为了安全，将文字样式表的状态切换为读
                st.DowngradeOpen();
            }

            return st[styleName];  //返回新添加的文字样式记录的ObjectId
        }
        /// <summary>
        /// 设置文字样式的有关属性
        /// </summary>
        /// <param name="styleId">文字样式的Id</param>
        /// <param name="textSize">文字的高度</param>
        /// <param name="XScale">宽度因子</param>
        /// <param name="obliquingAngle">倾斜角度</param>
        /// <param name="isVertical">是否垂直</param>
        /// <param name="upsideDown">是否上下颠倒</param>
        /// <param name="backwards">是否反向</param>
        /// <param name="annotative">是否具有注释性</param>
        /// <param name="paperOrientat">文字方向与布局是否匹配</param>
        public static void SetTextStyleProp(this ObjectId styleId, double textSize, double XScale, double obliquingAngle, bool isVertical, bool upsideDown, bool backwards, AnnotativeStates annotative, bool paperOrientat)
        {
            //打开文字样式表记录
            var str = styleId.GetObject(OpenMode.ForWrite) as TextStyleTableRecord;
            if (str == null) return; //如果styleId表示是不是文字样式表记录，则返回
            str.TextSize = textSize;  //高度
            str.XScale = XScale;  //宽度因子
            str.ObliquingAngle = obliquingAngle;   //倾斜角度
            str.IsVertical = isVertical;  //是否垂直
            str.FlagBits = (byte)0;
            str.FlagBits += upsideDown ? (byte)2 : (byte)0; //是否上下颠倒
            str.FlagBits += backwards ? (byte)4 : (byte)0; //是否反向
            str.Annotative = annotative;  //是否具有注释性
            str.SetPaperOrientation(paperOrientat);  //文字方向与布局是否匹配
            str.DowngradeOpen();  //为了安全，切换为读的状态
        }
        /// <summary>
        /// 设置单行文本的属性为当前文字样式的属性
        /// </summary>
        /// <param name="txt"></param>
        public static void SetFromTextStyle(this DBText txt)
        {
            //打开文字样式表记录
            var str = txt.TextStyleId.GetObject(OpenMode.ForRead) as TextStyleTableRecord;
            //必须保证文字为写的状态
            if (!txt.IsWriteEnabled) txt.UpgradeOpen();
            //设置倾斜角（角度）
            txt.Oblique = str.ObliquingAngle;
            //设置文字的注释性
            txt.Annotative = str.Annotative;
            //文字方向与布局是否匹配
            txt.SetPaperOrientation(Convert.ToBoolean(str.PaperOrientation));
            //设置宽度比例
            txt.WidthFactor = str.XScale;
            //设置高度
            txt.Height = str.TextSize;
            //颠倒
            if (str.FlagBits == 2)
            {
                txt.IsMirroredInX = true;
            }
            else if (str.FlagBits == 4)  //反向
            {
                txt.IsMirroredInY = true;
            }
            else if (str.FlagBits == 6)  //颠倒并反向
            {
                txt.IsMirroredInX = txt.IsMirroredInY = true;
            }
            //为了安全切换为读的状态
            txt.DowngradeOpen();
        }
    }
}
